package com.litong.vertx.hello;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.templ.thymeleaf.ThymeleafTemplateEngine;
import io.vertx.mysqlclient.MySQLClient;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.sqlclient.*;

import java.util.ArrayList;

/**
 * Created by litongjava@qq.com on 2020/9/9_21:46
 */
public class MainVerticle extends AbstractVerticle {
  //1.声明route
  private Router router;

  //1配置数据库连接参数
  MySQLConnectOptions connectOptions = new MySQLConnectOptions()
    .setPort(3306)
    .setHost("127.0.0.1")
    .setDatabase("vertx_study")
    .setUser("root")
    .setPassword("");
  //2配置连接池
  PoolOptions poolOptions = new PoolOptions()
    .setMaxSize(5);

  MySQLPool client;
  ThymeleafTemplateEngine thymeleafTemplateEngine;
  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    thymeleafTemplateEngine = ThymeleafTemplateEngine.create(vertx);

    //3 声明client
    client = MySQLPool.pool(vertx, connectOptions, poolOptions);

    long start = System.currentTimeMillis();
    //2.初始化route
    router = Router.router(vertx);
    //增加获取body参数
    router.route().handler(BodyHandler.create());
    //整合静态文件
    //router.route("/static/*").handler(StaticHandler.create());
    router.route("/*").handler(StaticHandler.create());
    //3.router和httpServer绑定
    HttpServer httpServer = vertx.createHttpServer().requestHandler(router);
    //4.添加route
    router.route("/hello").handler(req -> {
      HttpServerResponse response = req.response();
      response.putHeader("content-type", "text/plain");
      response.end("Hello from Vert.x!");
    });



    router.route("/json/object").handler(req -> {
      HttpServerResponse response = req.response();
      response.putHeader("content-type", "application/json");
      response.end(new JsonObject().put("hello", "vert.x!").toString());
    });

    router.route("/json/array").handler(req -> {
      JsonObject entries = new JsonObject().put("hello", "vert.x!");
      JsonArray objects = new JsonArray();
      objects.add(entries);
      req.response().putHeader("content-type", "application/json").end(objects.toString());
    });

    router.route("/hi").handler(new HiHanlder());

    //http://127.0.0.1:8888/url/kv?pageNo=1&pageSize=10
    router.route("/url/kv").handler(context -> {
      HttpServerRequest request = context.request();
      var pageNo = request.getParam("pageNo");
      var pageSize = request.getParam("pageSize");
      HttpServerResponse response = context.response();
      response.putHeader("content-type", "application/json");
      response.end(new JsonObject().put("pageNo", pageNo).put("pageSize", pageSize).toString());
    });
    //http://127.0.0.1:8888/url/rest/1/10
    router.route("/url/rest/:pageNo/:pageSize").handler(context -> {
      HttpServerRequest request = context.request();
      var pageNo = request.getParam("pageNo");
      var pageSize = request.getParam("pageSize");
      HttpServerResponse response = context.response();
      response.putHeader("content-type", "application/json");
      response.end(new JsonObject().put("pageNo", pageNo).put("pageSize", pageSize).toString());
    });
    router.route("/body/form").handler(context -> {
      HttpServerRequest request = context.request();
      var pageNo = request.getFormAttribute("pageNo");
      var pageSize = request.getFormAttribute("pageSize");

      HttpServerResponse response = context.response();
      response.putHeader("content-type", "application/json");
      response.end(new JsonObject().put("pageNo", pageNo).put("pageSize", pageSize).toString());
    });

    router.route("/body/json").handler(context -> {
      JsonObject entries = context.getBodyAsJson();
      HttpServerResponse response = context.response();
      response.putHeader("content-type", "application/json");
      response.end(entries.toString());
    });

    //测试mysql查询
    router.route("/mysql/select").handler(context -> {
      HttpServerResponse response = context.response();
      //拼接sql
      var tableName = "om_log_ask_detail_202008";
      var sqlTemplate = "select * from %s limit 0,10";
      String finalSql = String.format(sqlTemplate, tableName);
      // 获取连接
      client.getConnection(arg1 -> {
        //连接获取成功后在进行操作
        if (arg1.succeeded()) {
          System.out.println("succeeded");
          // 获取连接结果
          SqlConnection connection = arg1.result();
          //执行查询
          connection.query(finalSql).execute(ar2 -> {
            if (ar2.succeeded()) {
              //获取查询返回对象
              RowSet<Row> result = ar2.result();
              var list = new ArrayList<JsonObject>();
              result.forEach(item -> {
                var json = new JsonObject();
                json.put("id", item.getValue("ID"));
                json.put("question", item.getValue("QUESTION"));
                list.add(json);
              });
              response.putHeader("content-type", "application/json");
              response.end(list.toString());
            } else {
              //关闭连接
              connection.close();
              //输出连接失败信息
              response.end(ar2.cause().getMessage());
            }
          });
        } else {
          //输出连接失败信息
          System.out.println("could not get connection:" + arg1.cause().getMessage());
        }
      });
    });

    //测试mysql sql预编译 查询
    router.route("/mysql/list/:pageNo/:pageSize").handler(context -> {
      HttpServerResponse response = context.response();
      HttpServerRequest request = context.request();
      var pageNo = request.getParam("pageNo");
      var pageSize=request.getParam("pageSize");
      //拼接sql
      var tableName = "om_log_ask_detail_202008";
      var sqlTemplate = "select * from %s limit ?,?";
      String finalSql = String.format(sqlTemplate, tableName);
      // 获取连接
      client.getConnection(arg1 -> {
        //连接获取成功后在进行操作
        if (arg1.succeeded()) {
          System.out.println("succeeded");
          // 获取连接结果
          SqlConnection connection = arg1.result();
          //执行查询
          connection.preparedQuery(finalSql).execute(Tuple.of(pageNo,pageSize),ar2 -> {
            if (ar2.succeeded()) {
              //获取查询返回对象
              RowSet<Row> result = ar2.result();
              var list = new ArrayList<JsonObject>();
              result.forEach(item -> {
                var json = new JsonObject();
                json.put("id", item.getValue("ID"));
                json.put("question", item.getValue("QUESTION"));
                list.add(json);
              });
              response.putHeader("content-type", "application/json");
              response.end(list.toString());
            } else {
              //关闭连接
              connection.close();
              //输出连接失败信息
              response.end(ar2.cause().getMessage());
            }
          });
        } else {
          //输出连接失败信息
          System.out.println("could not get connection:" + arg1.cause().getMessage());
        }
      });
    });

    router.route("/").handler(context->{
      HttpServerResponse response = context.response();
      var jsonObject= new JsonObject();
      jsonObject.put("name","hello, thymeleaf");
      thymeleafTemplateEngine.render(jsonObject,"templates/index.html",buffAsyncResult->{
        if(buffAsyncResult.succeeded()){
          response.putHeader("content-type","text/html");
          response.end(buffAsyncResult.result());
        }else{
          response.end(buffAsyncResult.cause().getMessage());
        }

      });
    });
    //启动服务
    ListenHandler listenHandler = new ListenHandler(startPromise);
    httpServer.listen(8888, listenHandler);
    //计算服务启动时间
    long end = System.currentTimeMillis();
    System.out.println((end - start) + "ms");
  }
}
